Conversation
| } else { | ||
| XCTFail("Unexpected error: \(error)") | ||
| } | ||
| } |
There was a problem hiding this comment.
This test represents a breaking change: Before if you cleared the cache and requested the same info again, you would get nil for both the GraphQLResult and the Error. Now you will receive an error since there is nothing to decode for that result.
There was a problem hiding this comment.
That definitely seems correct to me, I think the previous behavior was a mistake.
| let websocketError = WebSocketError(payload: payload, | ||
| error: error, | ||
| kind: .neitherErrorNorPayloadReceived) | ||
| responseHandler(.failure(websocketError)) |
There was a problem hiding this comment.
This is a new error type to help handle cases where we previously could have sent nil for both the payload and the error.
There was a problem hiding this comment.
I don't have the full context here (this was contributed by someone else), but I'm wondering when this condition would actually occur. I suspect this is something that should be solved in OperationMessage.parse, because it seems like a protocol error.
There was a problem hiding this comment.
Yeah I plan to look at that in more depth when I do some much more detailed looks at the WebSocket stuff- this is at least to get this out the door in a way that still gives us some kind of semi-meaningful error about what went wrong.
| } else { | ||
| XCTFail("Unexpected error: \(error)") | ||
| } | ||
| } |
There was a problem hiding this comment.
This test also represents a breaking change - I think that this has an outer GraphQLResultError since there's some data in the cache, but not all of it.
|
Twitter feedback on this change has been positive so far - gonna let @martijnwalraven tell me what I'm doing wrong tomorrow and then leave it open for further feedback for a day or two. |
0e9fc98 to
bda9b6a
Compare
|
|
||
| @available(*, deprecated, renamed: "GraphQLResultHandler") | ||
| public typealias OperationResultHandler<Operation: GraphQLOperation> = GraphQLResultHandler<Operation.Data> | ||
| /// - result: The result of a performed operation. Will have a `GraphQLResult` with the data of the requested type on `success`, and an `Error` on `failure`. |
There was a problem hiding this comment.
Not sure if this is needed, but we may want to mention GraphQLResult can contain GraphQL errors in addition to data.
There was a problem hiding this comment.
Yeah good call
|
|
||
| func fetch(cachePolicy: CachePolicy) { | ||
| fetching = client?.fetch(query: query, cachePolicy: cachePolicy, context: &context) { [weak self] (result, error) in | ||
| fetching = client?.fetch(query: query, cachePolicy: cachePolicy, context: &context) { [weak self] outerResult in |
There was a problem hiding this comment.
I'm wondering if we can find a more descriptive name than outerResult, but I don't have any great suggestions. Or maybe just result and graphQLResult?
There was a problem hiding this comment.
yeah that works - i'll try to change that throughout when there's not a 2nd result being wrapped
| let websocketError = WebSocketError(payload: payload, | ||
| error: error, | ||
| kind: .neitherErrorNorPayloadReceived) | ||
| responseHandler(.failure(websocketError)) |
There was a problem hiding this comment.
I don't have the full context here (this was contributed by someone else), but I'm wondering when this condition would actually occur. I suspect this is something that should be solved in OperationMessage.parse, because it seems like a protocol error.
| } else { | ||
| XCTFail("Unexpected error: \(error)") | ||
| } | ||
| } |
There was a problem hiding this comment.
That definitely seems correct to me, I think the previous behavior was a mistake.
| } | ||
|
|
||
| client.fetch(query: query, cachePolicy: .returnCacheDataDontFetch) { (result, error) in | ||
| client.fetch(query: query, cachePolicy: .returnCacheDataDontFetch) { innerResult in |
There was a problem hiding this comment.
Why is this called innerResult here?
There was a problem hiding this comment.
Because this is a nested callback - we already have outerResult above.
bda9b6a to
d644a75
Compare
|
Hey, not an expert wrt. swift, but maybe one could add the old signature with a |
|
@mormahr Definitely doable, but it's pretty significant maintenance overhead to maintain all of the old public method signatures and basically need to do this with every single one: @available(*, deprecated, message: "Use the method with the `Result` completion handler instead")
func oldMethod(completion: @escaping (_ parameter: Parameter?, _ error: Error?)) {
self.newMethod { result in
switch result {
case .success(let parameter):
completion(parameter, nil)
case .failure(let error):
completion(nil, error)
}
}
}Unless there's a real good reason not to, I'd kinda prefer to rip the band-aid off here. |
|
OK folks - leaving this open for further comment until 10pm Netherlands Time (1pm US-Pacific) on Monday. Speak now or forever be mad at me for breaking your shit! |
…nforming to the `NetworkTransport` protocol
…gate` into extensions.
Yo dawg I heard you like Result so I put a Result in your Result
daca9bd to
c8b94d8
Compare
|
May [deity of choice] have mercy on us all. Merging! |
|
what's wrong with that, get a schema.json, but swift API |
This PR changes pretty much all of our completion closures to take advantage of Swift 5's built-in
Resulttype. This is going to be a SUPER-BREAKING CHANGE™, though I believe it will help significantly in disambiguating whether a particular request has succeeded or failed, which is why I've done it in the first place.If you have reasons you think I should abandon this path, I'd love to hear them - please let me know in the comments!
In this PR:
Resulttype to make it WAY easier to tell when a request has failed prior to parsing. This does cause a couple of significant changes:Previously, there were cases where we would return neither a result nor an error. These cases will now always return a result.
This leads to some extra-fun and inscrutable compiler errors when you're going through and updating everything:
What this error is attemping to tell you is that you need to change the two-parameter completion closure into a single-parameter one. It's telling you that in a very, very opaque fashion, though. I plan to document this in the release notes as well.
OperationResultHandlertypealias since I'm already breaking the crap out of everything